package com.lanchetech.admin.service.impl;


import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.admin.service.ShopService;
import com.lanchetech.admin.service.UserService;
import com.lanchetech.bean.request.*;
import com.lanchetech.bean.response.*;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.*;
import com.lanchetech.common.enums.*;
import com.lanchetech.common.exception.ResultCodeException;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.lanchetech.service.AnnouncementService;
import com.lanchetech.service.DaoService;
import com.lanchetech.service.JpushService;
import com.lanchetech.service.LevelService;
import com.lanchetech.service.KuaidizsService;
import org.apache.commons.lang3.StringUtils;
import org.hashids.Hashids;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.lanchetech.common.constants.JypConstant.*;


@Service
public class ShopServiceImpl implements ShopService {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    ShopMapper shopMapper;

    @Autowired
    AreaMapper areaMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    UserMapper userMapper;

    @Autowired
    UserRoleMapper userRoleMapper;

    @Autowired
    AppointmentSettingMapper appointmentSettingMapper;

    @Autowired
    ActivityRegisterMapper activityRegisterMapper;

    @Autowired
    BossMapper bossMapper;

    @Autowired
    IndustryMapper industryMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    UserInfoMapper userInfoMapper;

    @Autowired
    TenantMapper tenantMapper;

    @Autowired
    MerchantRoleMapper merchantRoleMapper;

    @Autowired
    MerchantPermissionMapper merchantPermissionMapper;

    @Autowired
    MerchantRolePermissionMapper merchantRolePermissionMapper;

    @Autowired
    MerchantMapper merchantMapper;

    @Autowired
    FreightMapper freightMapper;

    @Autowired
    ShopStatisticsMapper shopStatisticsMapper;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    SkuMapper skuMapper;

    @Autowired
    AnnouncementMapper announcementMapper;

    @Autowired
    ShopAnnouncementMapper shopAnnouncementMapper;

    @Autowired
    JpushService jpushService;

    @Autowired
    AnnouncementService announcementService;

    @Autowired
    BossInviteShopMapper bossInviteShopMapper;

    @Autowired
    BossIdentityMapper bossIdentityMapper;

    @Autowired
    KuaidizsLogisticsMapper kuaidizsLogisticsMapper;

    @Autowired
    OrdersMapper ordersMapper;

    @Autowired
    KuaidizsService kuaidizsService;

    private String appKey = "93CAB43C30E34F53B98D18E83FBFBE49";

    private String appSecret = "1AA8203422C948EE9419133730E76BFB";

    @Autowired
    LevelService levelService;
    @Autowired
    private UserService userService;
    @Autowired
    private ShopApplyMapper shopApplyMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResp editShop(Shop req) {
        Area area = areaMapper.selectByPrimaryKey(req.getArea());
        req.setMergerName(area.getMergerName());
        Date date = new Date();
        if (req.getId() == null) {
            Shop shop = shopMapper.findOneByPhone(req.getPhone());
            if (shop != null) {
                return new BaseResp(ResultCode.PHONE_EXISTS);
            }
            if (req.getKind() == null) {
                req.setKind(ShopKindEnum.PROJECT.getKind());
            }
            ShopApply apply = shopApplyMapper.findOneByPhone(req.getPhone());
            if (apply != null) {
                return new BaseResp(ResultCode.PHONE_ALREADY_EXISTS);
            }
            ShopApply shopApply = new ShopApply();
            shopApply.setPermitImage(req.getPermitImage());
            shopApply.setLogo(req.getLogo());
            shopApply.setProvince(req.getProvince());
            shopApply.setArea(req.getArea());
            shopApply.setCity(req.getCity());
            shopApply.setAccount(req.getAccount());
            shopApply.setLicenseValidTime(req.getLicenseValidTime());
            shopApply.setBank(req.getBank());
            shopApply.setOpenBank(req.getOpenBank());
            shopApply.setOpenName(req.getOpenName());
            shopApply.setMergerName(req.getMergerName());
            shopApply.setLicenseNumber(req.getLicenseNumber());
            shopApply.setLicenseImage(req.getLicenseImage());
            shopApply.setLicenseAddress(req.getAddress());
            shopApply.setLicenseLongTerm(req.getLicenseLongTerm());
            shopApply.setKind(req.getKind());
            shopApply.setShopType(req.getShopType());
            shopApply.setName(req.getName());
            shopApply.setLongitude(req.getLongitude());
            shopApply.setPhone(req.getPhone());
            shopApply.setAuditStatus((byte) 0);
            shopApply.setTenantName(req.getShopName());
            shopApply.setLatitude(req.getLatitude());
            shopApply.setAddress(req.getAddress());
            shopApply.setIdCardName(req.getIdCardName());
            shopApply.setTypeId(req.getTypeId());
            shopApply.setIdCardNumber(req.getIdCardNumber());
            shopApply.setIdCardBack(req.getIdCardBack());
            shopApply.setIdCardPositive(req.getIdCardPositive());
            shopApply.setIsRead((byte) 1);
            shopApply.setAvatar(req.getAvatar());
            shopApply.setFrontImage(req.getAvatar());
            shopApply.setEnvironmentImage(req.getEnvironmentImage());
            shopApply.setUserId(req.getUserId() == null ? null : req.getUserId());
            shopApply.setApplyType(req.getApplyType());
            shopApply.setIdCardCode(req.getIdCardCode());
            shopApply.setCertificateType(req.getCertificateType());
            shopApply.setIndustryFirstId(req.getIndustryFirstId());
            shopApply.setIndustrySecondId(req.getIndustrySecondId());
            shopApply.setTypeName(req.getTypeName());
            shopApply.setShopLevel(req.getShopLevel());
            shopApply.setIndustryName(req.getIndustryName());
//            shopApply.setShopOpenTime(req.getShopOpenTime());
            userService.editShopApply(shopApply);
        } else {
            // 更新tenant的状态
            tenantMapper.updateStatusById(req.getStatus(), req.getId());
            // 不允许修改平台服务费率
            req.setServiceRate(null);
            req.setUpdatedAt(date);
            shopMapper.updateByPrimaryKeySelective(req);
        }
        return new BaseResp();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResp applyShop(Shop shop) {

        Shop isNotShop = shopMapper.findOneByPhone(shop.getPhone());
        if (isNotShop != null) {
            return new BaseResp(ResultCode.PHONE_EXISTS);
        }
        if (shop.getKind() == null) {
            shop.setKind(ShopKindEnum.PROJECT.getKind());
        }

        Area area = areaMapper.selectByPrimaryKey(shop.getArea());
        shop.setMergerName(area.getMergerName());
        Date date = new Date();
        BigDecimal bigDecimal = new BigDecimal("5");
        shop.setCreatedAt(date);
        shop.setUpdatedAt(date);
        shop.setDeleted(DeletedEnum.DEFAULT.getStatus());
        shop.setOverallStar(bigDecimal);
        shop.setServiceStar(bigDecimal);
        shop.setEnvironmentStar(bigDecimal);
        shop.setValueStar(bigDecimal);
        shop.setServiceRate(daoService.getHipoConfigNumber(HipoConfigEnum.SERVICE_RATE.getConfig()));
        shopMapper.insert(shop);
        //新建商店统计数据表
        shopStatisticsMapper.insert(ShopStatistics.builder().shopId(shop.getId()).orderAmount(BigDecimal.ZERO).orderCount(0L).customCount(0L).visitCount(0L).viewCount(0L).createdAt(date).updatedAt(date).build());
        return createTenant(shop);
    }

    @Override
    public BaseResp editShopServiceRate(Shop req) {
        if (req.getServiceRate().compareTo(BigDecimal.ZERO) < 0 || req.getServiceRate().compareTo(BigDecimal.ONE) > 0) {
            return new BaseResp(ResultCode.FAIL);
        }
        shopMapper.updateServiceRateById(req.getServiceRate(), req.getId());

        // 同时更新此店所有未删除的sku的供货价
        // 如果是厂家，则是常规商品；如果是商家，则是
        Shop shop = shopMapper.selectByPrimaryKey(req.getId());

        skuMapper.batchUpdateCostPriceByTenantId(BigDecimal.ONE.subtract(req.getServiceRate()), req.getId(), ShopTypeEnum.PRODUCER.getType().equals(shop.getType()) ? SpuTypeEnum.ORDINARY.getType() : SpuTypeEnum.SHOP.getType());

        return new BaseResp();
    }

    @Override
    public BaseResp createTenant(Shop shop) {
        Merchant result = merchantMapper.getOneByUsername(shop.getPhone());
        if (result != null) {
            return new BaseResp(ResultCode.MERCHANT_EXISTS);
        }
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String rawPassword = "123456";
        Merchant merchant = Merchant.builder().roleId(INIT_ROLE_ID).username(shop.getPhone()).password(encoder.encode(rawPassword)).nickname(shop.getShopName()).avatar(MERCHANT_AVATAR).lastPasswordResetDate(new Date()).status(MerchantStatusEnum.NORMAL.getStatus()).createdAt(new Date()).updatedAt(new Date()).tenantId(INIT_TENANT_ID).registerName(shop.getShopName()).phone(shop.getPhone()).build();

        merchantMapper.register(merchant);

        auditTenant(Tenant.builder().id(shop.getId()).merchantId(merchant.getId()).tenantName(merchant.getRegisterName()).tenantNickname(merchant.getNickname()).contactName(merchant.getNickname()).status(ToggleEnum.ON.getStatus()).phone(merchant.getPhone()).province(shop.getProvince()).city(shop.getCity()).area(shop.getArea()).mergerName(shop.getMergerName()).address(shop.getAddress()).avatar(shop.getAvatar()).point(BigDecimal.ZERO).deleted(DeletedEnum.DEFAULT.getStatus()).createdAt(new Date()).updatedAt(new Date()).avatar(shop.getMainImage()).coin(BigDecimal.ZERO).account(shop.getAccount()).bank(shop.getBank()).openBank(shop.getOpenBank()).openName(shop.getOpenName()).licenseNumber(shop.getLicenseNumber()).licenseImage(shop.getLicenseImage()).licenseValidTime(shop.getLicenseValidTime()).licenseLongTerm(shop.getLicenseLongTerm()).idCardPositive(shop.getIdCardPositive()).idCardBack(shop.getIdCardBack()).idCardName(shop.getIdCardName()).build());

        return new BaseResp();
    }

    public BaseResp auditTenant(Tenant tenant) {
        Admin admin = (Admin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        tenant.setAuditStatus(TenantAuditStatusEnum.PASS.getStatus());
        tenant.setAuditTime(new Date());
        tenant.setAuditAdmin(admin.getUsername());
        tenantMapper.insertWithId(tenant);

        // 为商家创建默认的运费模板
        freightMapper.insert(Freight.builder().name("全国包邮-港澳台不配送（默认）").codes("110000,120000,130000,140000,150000,210000,220000,230000,310000,320000,330000,340000,350000,360000,370000,410000,420000,430000,440000,450000,460000,500000,510000,520000,530000,540000,610000,620000,630000,640000,650000").notDelivery("710000,810000,820000").firstWeight(BigDecimal.ZERO).additionalWeight(BigDecimal.ZERO).deleted(DeletedEnum.DEFAULT.getStatus()).createdAt(new Date()).updatedAt(new Date()).type(FreightTypeEnum.COUNT.getType()).tenantId(tenant.getId()).build());

        // 创建角色和权限
        MerchantRole merchantRole = MerchantRole.builder().name("ROLE_SUPER_MERCHANT").description("商家超级管理员").tenantId(tenant.getId()).build();
        merchantRoleMapper.insert(merchantRole);

        List<MerchantPermission> merchantPermissionList = merchantPermissionMapper.findAll();
        List<MerchantRolePermission> merchantRolePermissionList = new ArrayList<>();

        merchantPermissionList.stream().forEach(item -> {
            merchantRolePermissionList.add(MerchantRolePermission.builder().roleId(merchantRole.getId()).permissionId(item.getId()).build());
        });
        merchantRolePermissionMapper.batchInsert(merchantRolePermissionList);

        // 审核通过后，更新商户的tenantId, roleId
        merchantMapper.updateTenantIdAndRoleIdByIdAndTenantId(tenant.getId(), merchantRole.getId(), tenant.getMerchantId(), 0L);
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<ShopVO>> getShopPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Shop> list = shopMapper.findAllPage(req);
        List<ShopVO> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {

            List<Long> shopIds = list.stream().map(Shop::getId).collect(Collectors.toList());
            List<Boss> bossList = bossMapper.findAllByShopIds(shopIds);
            List<BossInviteShop> bossInviteList = bossInviteShopMapper.findAllByShopIds(shopIds);

            List<Long> userIds = new ArrayList<>();
            if (!bossList.isEmpty()) {
                userIds = bossList.stream().map(Boss::getUserId).collect(Collectors.toList());
            }

            if (!CollectionUtils.isEmpty(bossInviteList)) {
                userIds.addAll(bossInviteList.stream().map(BossInviteShop::getUserId).collect(Collectors.toList()));
            }

            for (Shop item : list) {
                if (item.getUserId() != null) {
                    userIds.add(item.getUserId());
                }
            }

            Map<Long, User> userMap = userIds.size() > 0 ? daoService.getUserMap(userIds) : new HashMap<>();


            Map<Long, User> bossMap = new HashMap<>();
            if (!bossList.isEmpty()) {
                bossList.stream().forEach(item -> {
                    bossMap.put(item.getShopId(), userMap.get(item.getUserId()));
                });
            }

            Map<Long, User> inviteBossMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(bossInviteList)) {
                bossInviteList.stream().forEach(item -> {
                    inviteBossMap.put(item.getShopId(), userMap.get(item.getUserId()));
                });
            }

            list.stream().forEach(item -> {
                ShopVO vo = new ShopVO();
                BeanUtils.copyProperties(item, vo);
                if (item.getUserId() != null) {
                    vo.setUserAvatar(userMap.get(item.getUserId()).getAvatar());
                    vo.setUserPhone(userMap.get(item.getUserId()).getUsername());
                    vo.setNickname(userMap.get(item.getUserId()).getNickname());
                }

                if (bossMap.containsKey(item.getId())) {
                    vo.setBossAvatar(bossMap.get(item.getId()).getAvatar());
                    vo.setBossPhone(bossMap.get(item.getId()).getUsername());
                    vo.setBossNickname(bossMap.get(item.getId()).getNickname());
                }

                if (inviteBossMap.containsKey(item.getId())) {
                    vo.setInviteBossPhone(inviteBossMap.get(item.getId()).getUsername());
                }
                result.add(vo);
            });
        }
        return PageHelpUtil.buildPage(result, page);
    }

    @Override
    public ResultData<Shop> getShopDetail(Long id) {
        return new ResultData<>(shopMapper.selectByPrimaryKey(id));
    }

    @Override
    public BaseResp deleteShop(Long id) {
        // 注意将来可能存在此店订货订单有，但没有相关的门店信息，因为门店被删除了
        shopMapper.updateDeletedAndUserIdById(DeletedEnum.DELETED.getStatus(), null, id);

        // 把用户角色下，此店的所有角色都删除
        userRoleMapper.deleteByRoleIdAndRelateId(UserRoleEnum.ROLE_SHOP.getId(), id);
        userRoleMapper.deleteByRoleIdAndRelateId(UserRoleEnum.ROLE_CLERK.getId(), id);
        userRoleMapper.deleteByRoleIdAndRelateId(UserRoleEnum.ROLE_BOSS.getId(), id);

        // 将商户关闭
        tenantMapper.updateStatusById(ToggleEnum.OFF.getStatus(), id);

        // 将商店下的所有管理员的密码修改时间更新，让所有人员都无法登录
        merchantMapper.updateLastPasswordResetDateByTenantId(new Date(), id);

        // 将所有商品设置为关闭状态
        spuMapper.updateHiddenByTenantId(HiddenEnum.HIDDEN.getStatus(), id);

        return new BaseResp();
    }

    @Override
    public BaseResp editShopUser(Long id, String phone) {
        // 目前规定：1家门店最多有且只有1个店主

        // 获取该用户
        User user = userMapper.findOneByUsername(phone);
        if (user == null) {
            return new BaseResp(ResultCode.ACCT_NOT_EXIST);
        }

        // 如果这个用户已经是其他门店的店主
        Shop result = shopMapper.findOneByUserId(user.getId());
        if (result != null) {
            return new BaseResp(ResultCode.SHOP_USER_EXISTS);
        }

        // 获取门店，如果门店之前已经有设置过店主，则要把店主删除掉
        Shop shop = shopMapper.selectByPrimaryKey(id);
        if (shop.getUserId() != null) {
            userRoleMapper.deleteByUserIdAndRoleId(shop.getUserId(), UserRoleEnum.ROLE_SHOP.getId());
        }

        // 设置门店店主
        shopMapper.updateUserIdById(user.getId(), shop.getId());


        // 同步设置用户的绑定商店
        userMapper.updateShopIdById(shop.getId(), user.getId());

        // 给店主添加店主角色
        userRoleMapper.insert(UserRole.builder().userId(user.getId()).roleId(UserRoleEnum.ROLE_SHOP.getId()).relateId(shop.getId()).name(shop.getShopName()).createdAt(new Date()).build());

        return new BaseResp();
    }

    @Override
    public BaseResp resetMerchantPassword(Long shopId) {
        Tenant tenant = tenantMapper.selectByPrimaryKey(shopId);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String rawPassword = "123456";
        merchantMapper.updatePasswordAndLastPasswordResetDateById(encoder.encode(rawPassword), new Date(), tenant.getMerchantId());
        return new BaseResp();
    }

    @Override
    public BaseResp editShopBoss(Long id, String phone, String name, String idCard) {

        // 无论这家店之前的老板是谁，都先删除，再插入新老板
        // 如果被更换了老板，则前老板仍然可以查看到之前的商店的记录，但之后的记录将不会有了。之前的钱也都还能提现。
        bossMapper.deleteByShopId(id);

        User user = userMapper.findOneByUsername(phone);

        if (user == null) {
            return new BaseResp(ResultCode.ACCT_NOT_EXIST);
        }
        bossMapper.insert(Boss.builder().shopId(id).userId(user.getId()).createdAt(new Date()).build());

        // 添加一个老板身份
        levelService.addOneBoss(user);

        // 保存用户的身份信息到userInfo
        UserInfo userInfo = UserInfo.builder().idCard(idCard).realName(name).userId(user.getId()).updatedAt(new Date()).build();
        userInfoMapper.updateIdCardAndRealNameAndUpdatedAtByUserId(userInfo);

        userMapper.updateShopIdById(id, user.getId());

        return new BaseResp();
    }

    @Override
    public BaseResp createShopInvite(Long id, String phone) {

        User user = userMapper.findOneByUsername(phone);

        if (user == null) {
            return new BaseResp(ResultCode.ACCT_NOT_EXIST);
        }

        // 检查是否已经存在推荐关系
        BossInviteShop bossInviteShop = bossInviteShopMapper.findOneByShopId(id);
        if (bossInviteShop == null) {
            // 增加邀请数量
            BossIdentity bossIdentity = bossIdentityMapper.findOneByUserId(user.getId());

            if (bossIdentity != null) {
                bossIdentity.setBossL1Number(bossIdentity.getBossL1Number() + 1);
                levelService.isBossPromotion(bossIdentity);

                bossInviteShopMapper.insert(BossInviteShop.builder().userId(user.getId()).shopId(id).performance(BigDecimal.ZERO).commission(BigDecimal.ZERO).createdAt(new Date()).updatedAt(new Date()).build());
            } else {
                return new BaseResp(ResultCode.NOT_HAVE_BOSS_IDENTITY);
            }
        } else {
            return new BaseResp(ResultCode.SHOP_INVITE_EXISTS);
        }

        return new BaseResp();
    }

    private void deleteRedisByKey(String key) {
        Set<String> keys = redisTemplate.keys(key);
        if (!CollectionUtils.isEmpty(keys)) {
            redisTemplate.delete(keys);
        }
    }

    @Override
    public BaseResp editAppointmentSetting(AppointmentSetting req) {

        AppointmentSetting result = appointmentSettingMapper.findOneBySpuId(req.getSpuId());

        if (result == null) {
            req.setCreatedAt(new Date());
            req.setUpdatedAt(new Date());
            req.setDeleted(DeletedEnum.DEFAULT.getStatus());
            appointmentSettingMapper.insert(req);
        } else {
            req.setId(result.getId());
            req.setUpdatedAt(new Date());
            appointmentSettingMapper.updateByPrimaryKeySelective(req);
        }
        deleteRedisByKey("ProductDetail:" + req.getSpuId() + ":*");
        return new BaseResp();
    }

    @Override
    public ResultData<AppointmentSetting> getAppointmentSettingBySpuId(Long spuId) {
        return new ResultData<>(appointmentSettingMapper.findOneBySpuId(spuId));
    }

    @Override
    public ResultData<BasePageResp<AppointmentSettingVO>> getAppointmentSettingPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<AppointmentSettingVO> list = appointmentSettingMapper.findAllPage(req);
        if (!list.isEmpty()) {
            Map<Long, Shop> shopMap = daoService.getShopMap(list.stream().map(AppointmentSettingVO::getShopId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setShopName(shopMap.get(item.getShopId()).getShopName());
                item.setShopMainImage(shopMap.get(item.getShopId()).getMainImage());
                item.setShopImageList(shopMap.get(item.getShopId()).getImageList());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }


    @Override
    public BaseResp auditActivityRegister(ActivityRegister activityRegister) {
        //查询需要修改的活动注册当前的状态
        ActivityRegister selectActivityRegister = activityRegisterMapper.selectByPrimaryKey(activityRegister.getId());
        if (selectActivityRegister.getStatus().equals(ActivityRegisterStatusEnum.PENDING.getStatus())) {
            activityRegister.setUpdatedAt(new Date());
            activityRegisterMapper.updateByPrimaryKeySelective(activityRegister);
        }
        return new BaseResp();
    }

    @Override
    public BaseResp deleteActivityRegister(Long id) {
        activityRegisterMapper.deleteByPrimaryKey(id);
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<ActivityRegisterVO>> getActivityRegisterPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<ActivityRegisterVO> list = activityRegisterMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(ActivityRegister::getUserId).collect(Collectors.toList()));
            Map<Long, Shop> shopMap = daoService.getShopMap(list.stream().map(ActivityRegister::getShopId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setUserNickname(userMap.get(item.getUserId()).getNickname());
                item.setShopName(shopMap.get(item.getShopId()).getShopName());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }


    @Override
    public ResultData<BasePageResp<IndustryVO>> getIndustryList(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<IndustryVO> list = industryMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, Industry> industryMap = daoService.getIndustryMap(list.stream().map(IndustryVO::getPid).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                //如果当前type为0 即为一级类目  不设置pname
                if (!item.getType().equals(IndustryTypeEnum.FIRST_ID.getType())) {
                    item.setPName(industryMap.get(item.getPid()).getName());
                }
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<List<IndustryVO>> getIndustry() {
        List<IndustryVO> list = industryMapper.findAll();
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, Industry> industryMap = daoService.getIndustryMap(list.stream().map(IndustryVO::getPid).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                //如果当前type为0 即为一级类目  不设置pname
                if (!item.getType().equals(IndustryTypeEnum.FIRST_ID.getType())) {
                    item.setPName(industryMap.get(item.getPid()).getName());
                }
            });
        }
        return new ResultData<>(list);
    }

    @Override
    public BaseResp editIndustry(Industry industry) {
        if (industry.getId() == null) {
            industry.setCreatedAt(new Date());
            industry.setUpdatedAt(new Date());
            industry.setDeleted(DeletedEnum.DEFAULT.getStatus());
            industryMapper.insert(industry);
        } else {
            industry.setUpdatedAt(new Date());
            industryMapper.updateByPrimaryKeySelective(industry);
        }
        return new BaseResp();
    }

    @Override
    public BaseResp deleteIndustry(Long id) {
        Industry industry = industryMapper.selectByPrimaryKey(id);
        if (industry != null && industry.getDeleted().equals(DeletedEnum.DEFAULT.getStatus())) {
            //如果一级类目
            if (industry.getType().equals(IndustryTypeEnum.FIRST_ID.getType())) {
                //所有子类目
                List<Industry> industries = industryMapper.selectAllIdByPid(id);
                List<Long> ids = new ArrayList<>();
                industries.stream().forEach(item -> {
                    ids.add(item.getId());
                });
                ids.add(id);
                industryMapper.updateDeletedByIds(ids);
            } else {
                //二级行业类目
                industryMapper.updateDeletedById(DeletedEnum.DELETED.getStatus(), id);
            }
        }
        return new BaseResp();
    }

    @Override
    public ResultData<List<IndustryIdAndNameVO>> getIndustryFirstList(Admin admin) {
        List<IndustryIdAndNameVO> list = industryMapper.selectNameAndIdByType(IndustryTypeEnum.FIRST_ID.getType());
        return new ResultData<>(list);
    }

    @Override
    public ResultData<List<IndustryIdAndNameVO>> getIndustrySecondList(PageReq req) {
        List<IndustryIdAndNameVO> list = industryMapper.selectNameAndIdBySelectivePid(req);
        return new ResultData<>(list);
    }

    @Override
    public BaseResp editAnnouncement(Announcement req) {
        if (req.getId() == null) {
            req.setCreatedAt(new Date());
            req.setUpdatedAt(new Date());
            req.setDeleted(DeletedEnum.DEFAULT.getStatus());
            announcementMapper.insert(req);
        } else {
            req.setUpdatedAt(new Date());
            announcementMapper.updateByPrimaryKeySelective(req);
        }
        return new BaseResp();
    }

    @Override
    public BaseResp sendAnnouncement(AnnouncementReq req) {
        List<Long> shopIds = req.getShopIds();
        Announcement announcement = announcementMapper.selectByPrimaryKey(req.getAnnouncementId());
        if (announcement == null || DeletedEnum.DELETED.getStatus().equals(announcement.getDeleted())) {
            return new BaseResp(ResultCode.ANNOUNCEMENT_NOT_EXIST);
        }
        List<User> userList;
        List<Long> allShopIds = shopMapper.findAllShopIds();
        Boolean isShopExist = true;
        if (CollectionUtils.isEmpty(shopIds)) {
            shopIds.addAll(allShopIds);
        } else {
            for (Long item : shopIds) {
                if (!allShopIds.contains(item)) {
                    isShopExist = false;
                    break;
                }
            }
            if (!isShopExist) {
                return new BaseResp(ResultCode.SHOP_NOT_EXIST);
            }
        }

        List<ShopAnnouncement> shopAnnouncements = new ArrayList<>();
        shopIds.stream().forEach(item -> {
            shopAnnouncements.add(ShopAnnouncement.builder().announcementId(announcement.getId()).shopId(item).catalog(announcement.getCatalog()).isRead(ToggleEnum.OFF.getStatus()).createdAt(new Date()).updatedAt(new Date()).build());
        });
        if (!CollectionUtils.isEmpty(shopAnnouncements)) {
            shopAnnouncementMapper.batchInsert(shopAnnouncements);
        }
        userList = userMapper.findAllByShopIdsAndRegistIdIsNotNull(shopIds);
        if (!CollectionUtils.isEmpty(userList)) {
            List<String> registerIds = userList.stream().map(User::getRegisterId).collect(Collectors.toList());
            jpushService.sendPushToPeople(announcement.getContent(), registerIds, announcement.getTitle(), null);
        }

        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<Announcement>> getAnnouncementPage(AnnouncementPageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Announcement> list = announcementMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<Announcement> getAnnouncementDetail(Long id) {
        return new ResultData<>(announcementMapper.selectByPrimaryKey(id));
    }

    @Override
    public BaseResp deleteAnnouncement(Long id) {
        announcementMapper.updateDeletedById(DeletedEnum.DELETED.getStatus(), id);
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<ShopAnnouncementVO>> getShopAnnouncementPage(ShopAnnouncementPageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<ShopAnnouncementVO> list = shopAnnouncementMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, Shop> shopMap = daoService.getShopMap(list.stream().map(ShopAnnouncementVO::getShopId).collect(Collectors.toList()));
            List<Announcement> announcementList = announcementMapper.findAllByIds(list.stream().map(ShopAnnouncementVO::getAnnouncementId).collect(Collectors.toList()));
            Map<Long, Announcement> announcementMap = new HashMap<>();
            announcementList.stream().forEach(item -> {
                announcementMap.put(item.getId(), item);
            });
            list.stream().forEach(item -> {
                item.setAnnouncement(announcementMap.get(item.getAnnouncementId()));
                item.setShopName(shopMap.get(item.getShopId()).getShopName());
                item.setShopAvatar(shopMap.get(item.getShopId()).getAvatar());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<List<Announcement>> getShopAnnouncementList() {
        return new ResultData<>(announcementMapper.findAll());
    }

    @Override
    public ResultData<BasePageResp<BossInviteShopVO>> getBossInviteShopPage(BossInviteShopReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<BossInviteShopVO> list = bossInviteShopMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(BossInviteShopVO::getUserId).collect(Collectors.toList()));
            Map<Long, Shop> shopMap = daoService.getShopMap(list.stream().map(BossInviteShopVO::getShopId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setBossAvatar(userMap.get(item.getUserId()).getAvatar());
                item.setBossNickname(userMap.get(item.getUserId()).getNickname());
                item.setShopName(shopMap.get(item.getShopId()).getShopName());
                item.setShopAvatar(shopMap.get(item.getShopId()).getAvatar());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<BossIdentityVO>> getBossIdentityPage(BossIdentityReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<BossIdentityVO> list = bossIdentityMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(BossIdentityVO::getUserId).collect(Collectors.toList()));
            Map<Long, Shop> shopMap = daoService.getShopMap(userMap.values().stream().map(User::getShopId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setBossAvatar(userMap.get(item.getUserId()).getAvatar());
                item.setBossNickname(userMap.get(item.getUserId()).getNickname());
                Long shopId = userMap.get(item.getUserId()).getShopId();
                if (shopId != null) {
                    item.setShopId(shopId);
                    item.setShopName(shopMap.get(shopId).getShopName());
                    item.setShopAvatar(shopMap.get(shopId).getAvatar());
                }
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public KdzsCallBackResp kuaidizsCallBack(Map<String, String> params) {
        try {
            log.info("接收到快递助手回调信息{}", params);
            String sign = params.get("sign");
            String buildString = buildSignString(params);
            String buildSign = DigestUtils.md5DigestAsHex(buildString.getBytes(StandardCharsets.UTF_8));
            if (buildSign.equalsIgnoreCase(sign)) {
                String method = params.get("method");
                if ("trade.send".equals(method)) {
                    log.info("接收到发货回调");
                    KdzsTradeSendVO appParam = JSON.parseObject(params.get("appParam"), KdzsTradeSendVO.class);
                    Orders orders = ordersMapper.selectByPrimaryKey(Long.valueOf(appParam.getTid()));
                    orders.setLogisticsStatus(LogisticsStatusEnum.DONE.getStatus());
                    orders.setLogisticsCompany(kuaidizsLogisticsMapper.findOneByKdzsCode(appParam.getCompanyCode()).getCode());
                    orders.setLogisticsNumber(appParam.getWaybillNo());
                    orders.setDeliveryTime(new Date());
                    ordersMapper.updateByPrimaryKeySelective(orders);
                } else if ("user.push".equals(method)) {
                    log.info("接收到店铺首次登陆回调");
                    UserPushVO appParam = JSON.parseObject(params.get("appParam"), UserPushVO.class);
                    String token = appParam.getToken();
                    Hashids hashids = new Hashids("kuaidizs", 16);
                    Long id = hashids.decode(token)[0];
                    Shop shop = shopMapper.selectByPrimaryKey(id);
                    if (shop != null) {
                        //更新malluserId
                        shopMapper.updateMallUserIdById(appParam.getMallUserId(), id);
                    } else {
                        log.info("首次登陆信息不正确");
                        return KdzsCallBackResp.builder().code(400).build();
                    }
                } else if ("user.login".equals(method)) {
                    log.info("接收到店铺登陆回调");
                    UserPushVO appParam = JSON.parseObject(params.get("appParam"), UserPushVO.class);
                    String token = appParam.getToken();
                    Hashids hashids = new Hashids("kuaidizs", 16);
                    Long id = hashids.decode(token)[0];
                    Shop shop = shopMapper.selectByPrimaryKey(id);
                    if (shop == null) {
                        log.info("登陆信息不正确");
                        return KdzsCallBackResp.builder().code(400).build();
                    }
                } else {
                    log.info("接收未知类型回调{}", method);
                }
            } else {
                log.info("签名校验失败");
            }
        } catch (Exception e) {
            log.info("接收回调信息异常{}", e.getMessage());
            e.printStackTrace();
        }
        return KdzsCallBackResp.builder().code(200).build();
    }

    private String buildSignString(Map<String, String> params) {
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);

        StringBuilder query = new StringBuilder();
        query.append(appSecret);
        for (String key : keys) {
            String value = params.get(key);
            if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value) && !key.equals("sign")) {
                query.append(key).append("=").append(value).append("&");
            }
        }
        String substring = query.substring(0, query.length() - 1);
        return substring + appSecret;
    }

    @Override
    public BaseResp verify(Long id, boolean verify) throws ResultCodeException {
        TenantInfoVO tenantInfoVO = shopMapper.getTenantInfoById(id);
        if (null == tenantInfoVO) {
            throw new ResultCodeException(ResultCode.FAIL);
        }
        shopMapper.verify(id, verify);
        return new BaseResp();
    }
}

